home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / fs / main.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  17KB  |  564 lines

  1. /* This file contains the main program of the File System.  It consists of
  2.  * a loop that gets messages requesting work, carries out the work, and sends
  3.  * replies.
  4.  *
  5.  * The entry points into this file are
  6.  *   main:    main program of the File System
  7.  *   reply:    send a reply to a process after the requested work is done
  8.  */
  9.  
  10. #include "fs.h"
  11. #include <minix/callnr.h>
  12. #include <minix/com.h>
  13. #include <minix/boot.h>
  14. #include "buf.h"
  15. #include "file.h"
  16. #include "fproc.h"
  17. #include "inode.h"
  18. #include "param.h"
  19. #include "super.h"
  20.  
  21. #if FASTLOAD
  22. #include "dev.h"
  23. #endif
  24.  
  25. #define M64K     0xFFFF0000L    /* 16 bit mask for DMA check */
  26. #define MAX_RAM        16384    /* maximum RAM disk size in blocks */
  27. #define RAM_IMAGE (dev_t)0x303    /* major-minor dev where root image is kept */
  28. #define DEMO_RAM_OFFSET  200    /* location of RAM image on demo diskette */
  29.  
  30. FORWARD void buf_pool();
  31. FORWARD void fs_init();
  32. FORWARD void get_boot_parameters();
  33. FORWARD void get_work();
  34. FORWARD dev_t load_ram();
  35. FORWARD void load_super();
  36.  
  37. #if ASKDEV
  38. FORWARD int askdev();
  39. #endif
  40.  
  41. #if FASTLOAD
  42. FORWARD void fastload();
  43. FORWARD int lastused();
  44. #endif
  45.  
  46. #if (CHIP == INTEL)
  47. FORWARD phys_bytes get_physbase();
  48. #endif
  49.  
  50. /*===========================================================================*
  51.  *                main                         *
  52.  *===========================================================================*/
  53. PUBLIC void main()
  54. {
  55. /* This is the main program of the file system.  The main loop consists of
  56.  * three major activities: getting new work, processing the work, and sending
  57.  * the reply.  This loop never terminates as long as the file system runs.
  58.  */
  59.   int error;
  60.  
  61.   fs_init();
  62.  
  63.   /* This is the main loop that gets work, processes it, and sends replies. */
  64.   while (TRUE) {
  65.     get_work();        /* sets who and fs_call */
  66.  
  67.     fp = &fproc[who];    /* pointer to proc table struct */
  68.     super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE);   /* su? */
  69.     dont_reply = FALSE;    /* in other words, do reply is default */
  70.  
  71.     /* Call the internal function that does the work. */
  72.     if (fs_call < 0 || fs_call >= NCALLS)
  73.         error = EBADCALL;
  74.     else
  75.         error = (*call_vector[fs_call])();
  76.  
  77.     /* Copy the results back to the user and send reply. */
  78.     if (dont_reply) continue;
  79.     reply(who, error);
  80.     if (rdahed_inode != NIL_INODE) read_ahead(); /* do block read ahead */
  81.   }
  82. }
  83.  
  84.  
  85. /*===========================================================================*
  86.  *                get_work                     *
  87.  *===========================================================================*/
  88. PRIVATE void get_work()
  89. {  
  90.   /* Normally wait for new input.  However, if 'reviving' is
  91.    * nonzero, a suspended process must be awakened.
  92.    */
  93.  
  94.   register struct fproc *rp;
  95.  
  96.   if (reviving != 0) {
  97.     /* Revive a suspended process. */
  98.     for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++) 
  99.         if (rp->fp_revived == REVIVING) {
  100.             who = (int)(rp - fproc);
  101.             fs_call = rp->fp_fd & BYTE;
  102.             fd = (rp->fp_fd >>8) & BYTE;
  103.             buffer = rp->fp_buffer;
  104.             nbytes = rp->fp_nbytes;
  105.             rp->fp_suspended = NOT_SUSPENDED; /*no longer hanging*/
  106.             rp->fp_revived = NOT_REVIVING;
  107.             reviving--;
  108.             return;
  109.         }
  110.     panic("get_work couldn't revive anyone", NO_NUM);
  111.   }
  112.  
  113.   /* Normal case.  No one to revive. */
  114.   if (receive(ANY, &m) != OK) panic("fs receive error", NO_NUM);
  115.  
  116.   who = m.m_source;
  117.   fs_call = m.m_type;
  118. }
  119.  
  120.  
  121. /*===========================================================================*
  122.  *                reply                         *
  123.  *===========================================================================*/
  124. PUBLIC void reply(whom, result)
  125. int whom;            /* process to reply to */
  126. int result;            /* result of the call (usually OK or error #) */
  127. {
  128. /* Send a reply to a user process. It may fail (if the process has just
  129.  * been killed by a signal), so don't check the return code.  If the send
  130.  * fails, just ignore it.
  131.  */
  132.  
  133.   reply_type = result;
  134.   send(whom, &m1);
  135. }
  136.  
  137. /*===========================================================================*
  138.  *                fs_init                         *
  139.  *===========================================================================*/
  140. PRIVATE void fs_init()
  141. {
  142. /* Initialize global variables, tables, etc. */
  143.  
  144.   register struct inode *rip;
  145.   int i;
  146.   dev_t d;            /* device to fetch the superblock from */
  147.  
  148.   buf_pool();            /* initialize buffer pool */
  149.   get_boot_parameters();
  150.   d = load_ram();        /* init RAM disk, load if it is root */
  151.   load_super(d);        /* Load super block for root device */
  152.  
  153.   /* Initialize the 'fproc' fields for process 0 and process 2. */
  154.   for (i = 0; i < 3; i+= 2) {
  155.     fp = &fproc[i];
  156.     rip = get_inode(ROOT_DEV, ROOT_INODE);
  157.     fp->fp_rootdir = rip;
  158.     dup_inode(rip);
  159.     fp->fp_workdir = rip;
  160.     fp->fp_realuid = (uid_t) SYS_UID;
  161.     fp->fp_effuid = (uid_t) SYS_UID;
  162.     fp->fp_realgid = (gid_t) SYS_GID;
  163.     fp->fp_effgid = (gid_t) SYS_GID;
  164.     fp->fp_umask = ~0;
  165.   }
  166.  
  167.   /* Certain relations must hold for the file system to work at all. */
  168.   if (ZONE_NUM_SIZE != 2) panic("ZONE_NUM_SIZE != 2", NO_NUM);
  169.   if (SUPER_SIZE > BLOCK_SIZE) panic("SUPER_SIZE > BLOCK_SIZE", NO_NUM);
  170.   if(BLOCK_SIZE % INODE_SIZE != 0)panic("BLOCK_SIZE % INODE_SIZE != 0",NO_NUM);
  171.   if (OPEN_MAX > 127) panic("OPEN_MAX > 127", NO_NUM);
  172.   if (NR_BUFS < 6) panic("NR_BUFS < 6", NO_NUM);
  173.   if (sizeof(d_inode) != 32) panic("inode size != 32", NO_NUM);
  174. }
  175.  
  176. /*===========================================================================*
  177.  *                buf_pool                     *
  178.  *===========================================================================*/
  179. PRIVATE void buf_pool()
  180. {
  181. /* Initialize the buffer pool.  On the IBM PC, the hardware DMA chip is
  182.  * not able to cross 64K boundaries, so any buffer that happens to lie
  183.  * across such a boundary is not used.  This is not very elegant, but all
  184.  * the alternative solutions are as bad, if not worse.  The fault lies with
  185.  * the PC hardware.
  186.  */
  187.   register struct buf *bp;
  188.  
  189.   vir_bytes low_off, high_off;        /* only used on INTEL chips */
  190.   phys_bytes org;
  191.  
  192.   bufs_in_use = 0;
  193.   front = &buf[0];
  194.   rear = &buf[NR_BUFS - 1];
  195.  
  196.   for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++) {
  197.     bp->b_blocknr = NO_BLOCK;
  198.     bp->b_dev = NO_DEV;
  199.     bp->b_next = bp + 1;
  200.     bp->b_prev = bp - 1;
  201.   }
  202.   buf[0].b_prev = NIL_BUF;
  203.   buf[NR_BUFS - 1].b_next = NIL_BUF;
  204.  
  205.   /* Delete any buffers that span a 64K boundary, by marking them as used. */
  206. #if (CHIP == INTEL)
  207.   for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++) {
  208.     org = get_physbase();    /* phys addr where FS is */
  209.     low_off = (vir_bytes) bp->b_data;
  210.     high_off = low_off + BLOCK_SIZE - 1;
  211.     if (((org + low_off) & M64K) != ((org + high_off) & M64K)) {
  212.         ++bp->b_count;    /* it was 0, by static initialization */
  213.         ++bufs_in_use;
  214.     }
  215.   }
  216. #endif
  217.  
  218.   for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++) bp->b_hash = bp->b_next;
  219.   buf_hash[NO_BLOCK & (NR_BUF_HASH - 1)] = front;
  220. }
  221.  
  222.  
  223. /*===========================================================================*
  224.  *                load_ram                     *
  225.  *===========================================================================*/
  226. PRIVATE dev_t load_ram()
  227. {
  228. /* If the root device is the RAM disk, copy the entire root image device
  229.  * block-by-block to a RAM disk with the same size as the image.
  230.  * Otherwise, just allocate a RAM disk with size given in the boot parameters.
  231.  */
  232.  
  233.   register struct buf *bp, *bp1;
  234.   int count;
  235.   long k_loaded;
  236.   struct super_block *sp;
  237.   block_nr ram_offset = 0;    /* block offset of RAM image on demo diskette*/
  238.   block_nr i, b;
  239.   dev_t root_device;        /* really the root image device */
  240.   dev_t super_dev;        /* device to get superblock from */
  241.   phys_clicks ram_clicks, init_org, init_text_clicks, init_data_clicks;
  242.  
  243.   /* Get size of INIT by reading block on diskette where 'build' put it. */
  244.   init_org = data_org[INFO];
  245.   init_text_clicks = data_org[INFO + 1];
  246.   init_data_clicks = data_org[INFO + 2];
  247.  
  248.   /* Print ATARI copyright message. */
  249. #if (MACHINE == ATARI)
  250.   printf("Booting MINIX 1.5.  Copyright 1990 Prentice-Hall, Inc.\n");
  251. #endif
  252.  
  253.   /* If the root device is specified in the boot parameters, use it. */
  254.   if (ROOT_DEV != DEV_RAM) {
  255.     count = boot_parameters.bp_ramsize;
  256.     super_dev = ROOT_DEV;    /* get superblock directly from root device */
  257.     goto got_root_dev;    /* kludge to avoid excessive indent/diffs */
  258.   } else {
  259.     super_dev = DEV_RAM;    /* get superblock from RAM disk */
  260.   }
  261.  
  262.   /* Get size of RAM disk by reading root